#pragma once

#include "Sock.hpp"
#include <functional>
#include <cassert>
#include <signal.h>


using func_t = std::function<void(int)>;

class HttpServer {
public:
  HttpServer(uint16_t port, func_t fun)
    :_listenSock(-1)
    ,_fun(fun)
  {
    _listenSock = _sock.Socket();
    assert(_listenSock != -1);
    _sock.Bind(_listenSock, port);
    _sock.Listen(_listenSock);
  }

  void Start() {
    signal(SIGCHLD, SIG_IGN);
    while(1) {
      std::string clientIp;
      uint16_t clientPort;
      int serverSock = _sock.Accept(_listenSock, clientIp, clientPort);

      if(serverSock < 0) {
        std::cout << "accept fail" << std::endl;
        continue;
      }
      
      if(fork() == 0) {
        close(_listenSock);
        _fun(serverSock);
        close(serverSock);
        exit(0);
      }
      close(serverSock);
    }
  }
  
  ~HttpServer() {
    if(_listenSock >= 0) {
      close(_listenSock);
    }
  }
  
private:
  int _listenSock;
  Sock _sock;
  func_t _fun;
};
